package cn.iocoder.yudao.module.infra.controller.admin.face;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.infra.api.face.dto.FaceOperationRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.face.vo.FaceDeleteReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.face.vo.FaceDetectBase64ReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.face.vo.FaceRegisterBase64ReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.face.vo.FaceSearchBase64ReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.face.vo.FaceSearchRespVO;
import cn.iocoder.yudao.module.infra.service.face.FaceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.USER_NOT_LOGIN;


/**
 * 管理后台 - 人脸识别
 *
 * @author 芋道源码
 */
@Tag(name = "管理后台 - 人脸识别")
@RestController
@RequestMapping("/infra/face")
@Validated
@Slf4j
public class FaceController {

    @Resource
    private FaceService faceService;

    @PostMapping("/register")
    @Operation(summary = "人脸注册")
    @PreAuthorize("@ss.hasPermission('infra:face:register')")
    public CommonResult<Map<String, Object>> registerFace(
            @RequestParam("groupId") String groupId,
            @RequestParam("faceImage") MultipartFile faceImage) {
        // 获取当前登录用户ID
        Long currentUserId = SecurityFrameworkUtils.getLoginUserId();
        if (currentUserId == null) {
            throw exception(USER_NOT_LOGIN);
        }
        return success(faceService.registerFace(currentUserId, faceImage, groupId));
    }

    @PostMapping("/search")
    @Operation(summary = "人脸搜索")
    @PreAuthorize("@ss.hasPermission('infra:face:search')")
    public CommonResult<Map<String, Object>> searchFace(
            @RequestParam("configId") String configId,
            @RequestParam("faceImage") MultipartFile faceImage) {
        // 验证用户是否登录
        Long currentUserId = SecurityFrameworkUtils.getLoginUserId();
        if (currentUserId == null) {
            throw exception(USER_NOT_LOGIN);
        }
        return success(faceService.searchFace(faceImage, configId));
    }

    @PostMapping("/detect")
    @Operation(summary = "人脸检测")
    @Parameter(name = "faceImage", description = "人脸图片", required = true)
    @PreAuthorize("@ss.hasPermission('infra:face:detect')")
    public CommonResult<Map<String, Object>> detectFace(@RequestParam("faceImage") MultipartFile faceImage) {
        // 验证用户是否登录
        Long currentUserId = SecurityFrameworkUtils.getLoginUserId();
        if (currentUserId == null) {
            throw exception(USER_NOT_LOGIN);
        }
        Map<String, Object> result = faceService.detectFace(faceImage);
        return success(result);
    }

    @PostMapping("/verify")
    @Operation(summary = "人脸验证")
    @Parameter(name = "userId", description = "用户ID", required = true)
    @Parameter(name = "faceImage", description = "人脸图片", required = true)
    @PreAuthorize("@ss.hasPermission('infra:face:verify')")
    public CommonResult<Map<String, Object>> verifyFace(@RequestParam("userId") @NotNull Long userId,
                                                        @RequestParam("faceImage") MultipartFile faceImage) {
        Map<String, Object> result = faceService.verifyFace(userId, faceImage);
        return success(result);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除人脸")
    @PreAuthorize("@ss.hasPermission('infra:face:delete')")
    public CommonResult<Boolean> deleteFace(@Valid @RequestBody FaceDeleteReqVO deleteReqVO) {
        // 验证用户是否登录
        Long currentUserId = SecurityFrameworkUtils.getLoginUserId();
        if (currentUserId == null) {
            throw exception(USER_NOT_LOGIN);
        }
        // 设置当前登录用户ID，确保用户只能删除自己的人脸数据
        deleteReqVO.setUserId(currentUserId);
        return success(faceService.deleteFace(deleteReqVO));
    }

    // ========== Base64 版本的接口 ==========

    @PostMapping("/register-base64")
    @Operation(summary = "人脸注册 - Base64")
    @PreAuthorize("@ss.hasPermission('infra:face:register')")
    public CommonResult<FaceOperationRespVO> registerFaceBase64(@Valid @RequestBody FaceRegisterBase64ReqVO registerReqVO) {
        // 获取当前登录用户ID
        Long currentUserId = SecurityFrameworkUtils.getLoginUserId();
        if (currentUserId == null) {
            throw exception(USER_NOT_LOGIN);
        }
        // 设置当前登录用户ID
        registerReqVO.setUserId(String.valueOf(currentUserId));
        FaceOperationRespVO result = faceService.registerFaceBase64(registerReqVO);
        return success(result);
    }

    @PostMapping("/search-base64")
    @Operation(summary = "人脸搜索（Base64）")
    @PreAuthorize("@ss.hasPermission('infra:face:search')")
    public CommonResult<FaceSearchRespVO> searchFaceBase64(@Valid @RequestBody FaceSearchBase64ReqVO searchReqVO) {
        // 验证用户是否登录
        Long currentUserId = SecurityFrameworkUtils.getLoginUserId();
        if (currentUserId == null) {
            throw exception(USER_NOT_LOGIN);
        }
        return success(faceService.searchFaceBase64(searchReqVO));
    }

    @PostMapping("/detect-base64")
    @Operation(summary = "人脸检测（Base64）")
    @PreAuthorize("@ss.hasPermission('infra:face:detect')")
    public CommonResult<String> detectFaceBase64(@RequestBody @Valid FaceDetectBase64ReqVO detectReqVO) {
        // 验证用户是否登录
        Long currentUserId = SecurityFrameworkUtils.getLoginUserId();
        if (currentUserId == null) {
            throw exception(USER_NOT_LOGIN);
        }
        return success(faceService.detectFaceBase64(detectReqVO));
    }

}